//
//  SessionManager.m
//  PicoYPlaca
//
//  Created by Mario Franco on 12/6/12.
//  Copyright (c) 2012 DmpmMacPro. All rights reserved.
//

#import "SessionManager.h"
#import "PicoYPlaca.h"
#import "Persistencia.h"
#import "Comunicacion.h"
#import "Ciudad.h"
#import "TipoVehiculo.h"
#import "Regla.h"
#import "Horario.h"
#import "Tabla.h"
#import "Columna.h"


@implementation SessionManager
PicoYPlaca *picoYPlaca;
Persistencia * persistencia;
Comunicacion * comunicacion;

- (id)init
{
    self = [super init];
    if (self)
    {
        picoYPlaca = [[PicoYPlaca alloc] init];
        persistencia = [[Persistencia alloc] init];
        comunicacion = [[Comunicacion alloc] init];
        
        [persistencia revisarExistenciaArchivos];
        // [self actualizarTablasLocales];
        
        
        //  [self cargarMundoPicoYPlaca];
    }
    return self;
}

+(SessionManager *)darInstancia
{
    static dispatch_once_t predicate = 0;
    __strong static SessionManager* _instancia = nil;
    
    dispatch_once(&predicate, ^{
        // --- call to super avoids a deadlock with the above allocWithZone
        _instancia = [[super alloc] init];
    });
    
    return _instancia;
}

-(void) cargarMundoPicoYPlaca
{
    // Se carga la info de las tablas
    if(![self cargarPicoYPlaca])
    {
        NSLog(@"Falló la carga...");
        //picoYPlaca = [[PicoYPlaca alloc] initTest];
    }
    [persistencia vaciarTablas];
    
    [self cargarTipoVehiculosFavoritos];
}

/*
 * Retorna Yes si encuentra alguna diferencia y actualiza las tablas locales.
 */
- (BOOL) actualizarTablasLocales
{
    
    BOOL encontroDiferencia = NO;
    if ([Comunicacion hayConexion])
    {
        // Se verifican las versiones de las tablas
        NSDictionary * dictActuales = [persistencia darVersionesDeArchivos];
        encontroDiferencia = [comunicacion actualizarTablasLocales:dictActuales];
        
        //Se guardan las nuevas versiones de las tablas
        [persistencia actualizarArchivoVersiones:dictActuales];
    }
    
    return encontroDiferencia;
    
}


-(NSMutableArray *) darFavoritos
{
    return picoYPlaca.favoritos;
}

-(TipoVehiculo *) darFavorito
{
    return picoYPlaca.favorito;
}

-(void) establecerFavorito:(TipoVehiculo*)tipoVehiculo
{
    picoYPlaca.favorito = tipoVehiculo;
}

-(NSMutableArray *) darCiudades
{
    return picoYPlaca.ciudades;
}

- (BOOL) cargarPicoYPlaca
{
    
    //FORMATO FECHAS
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"dd/MM/yyyy"];
    
    NSDateFormatter *formatoHora = [[NSDateFormatter alloc] init];
    [formatoHora setDateFormat:@"dd/MM/yyyy hh:mma"];
    
    [formatoHora setPMSymbol:@"pm"];
    [formatoHora setAMSymbol:@"am"];
    
    [persistencia cargarTablasPicoyPlaca];
    
    Tabla * horarios = [persistencia darTablaDeNombre:@"Horarios"];
    Tabla * restricciones = [persistencia darTablaDeNombre:@"Restricciones"];
    Tabla * tiposVehiculos = [persistencia darTablaDeNombre:@"Tipos_vehiculos"];
    
    NSMutableArray * ciudades = [[NSMutableArray alloc] init];
    
    
    if(!horarios || !restricciones || !tiposVehiculos)
    {
        
        NSLog(@"No cargó bien las tablas");
        return NO;
    }
    
    Columna * colFecha = [horarios.columnas objectAtIndex:0];
    // Columna * colFestivo = [horarios.columnas objectAtIndex:horarios.columnas.count-1];
    
    // Crear estructura de ciudades y vehiculos
    for (int i = 1; i < restricciones.columnas.count; i++)
    {
        
        Columna * colRestriccionesActual = [horarios.columnas objectAtIndex:i];
        NSArray * temp = [colRestriccionesActual.nombre componentsSeparatedByString:@" - "];
        
        
        NSString * ciudad = [temp objectAtIndex:0];
        NSString * tipoVehi = [temp objectAtIndex:1];
        
        BOOL encontroCiudad = NO;
        
        for (int k = 0;k < ciudades.count && !encontroCiudad; k++)
        {
            Ciudad * ciuTemp = [ciudades objectAtIndex:k];
            if ([ciuTemp.nombre isEqualToString:ciudad])
            {
                encontroCiudad= YES;
                
                TipoVehiculo * tipoN = [[TipoVehiculo alloc] init];
                tipoN.tipo = tipoVehi;
                tipoN.ciudad = ciuTemp;
                [ciuTemp.tiposVehiculos addObject:tipoN];
            }
        }
        if(!encontroCiudad)
        {
            Ciudad * ciuTemp = [[Ciudad alloc] init];
            ciuTemp.nombre = ciudad;
            TipoVehiculo * tipoN = [[TipoVehiculo alloc] init];
            tipoN.tipo = tipoVehi;
            tipoN.ciudad = ciuTemp;
            [ciuTemp.tiposVehiculos addObject:tipoN];
            
            [ciudades addObject:ciuTemp];
        }
        
        
        
    }
    
    
    
    // Agregar Reglas
    for (int i =0 ; i < colFecha.datos.count  ; i++)
    {
        NSDate * fechaTemp = [formatter dateFromString:[colFecha.datos objectAtIndex:i]];
        NSMutableArray * reglasTemp = [[NSMutableArray alloc] init];
        for (int j = 0; j < horarios.columnas.count; j++)
        {
            Columna * colHorariosActual = [horarios.columnas objectAtIndex:j];
            Columna * colRestriccionesActual = nil;
            
            if(j < restricciones.columnas.count)
            {
                colRestriccionesActual = [restricciones.columnas objectAtIndex:j];
            }
            
            if ([colHorariosActual.nombre isEqualToString:@"Fecha"])
            {
                //fechaTemp = [colHorariosActual.datos objectAtIndex:i];
            }
            else if([colHorariosActual.nombre isEqualToString:@"Es festivo"])
            {
                for (Regla * reg in reglasTemp)
                {
                    
                    reg.esFestivo = [[colHorariosActual.datos objectAtIndex:i] isEqualToString:@"Sí"];
                }
                
            }
            else if(![[colHorariosActual.datos objectAtIndex:i] isEqualToString:@""])
            {
                NSString * ciudad = [[colHorariosActual.nombre componentsSeparatedByString:@" - "] objectAtIndex:0];
                NSString * tipoVehi = [[colHorariosActual.nombre componentsSeparatedByString:@" - "] objectAtIndex:1];
                
                BOOL encontroCiudad = NO;
                BOOL encontroTipo = NO;
                for (int k = 0;k < ciudades.count && !encontroCiudad; k++)
                {
                    
                    Ciudad * ciuTemp = [ciudades objectAtIndex:k];
                    
                    if ([ciuTemp.nombre isEqualToString:ciudad])
                    {
                        encontroCiudad= YES;
                        
                        for (int l = 0; l < ciuTemp.tiposVehiculos.count && !encontroTipo; l++)
                        {
                            TipoVehiculo * tipoN = [ciuTemp.tiposVehiculos objectAtIndex:l];
                            if([tipoN.tipo isEqualToString:tipoVehi])
                            {
                                encontroTipo = YES;
                                
                                Regla * regla = [[Regla alloc] init];
                                regla.numeros = [colRestriccionesActual.datos objectAtIndex:i];
                                regla.fecha = fechaTemp;
                                
                                NSArray * horarTemps = [[colHorariosActual.datos objectAtIndex:i] componentsSeparatedByString:@" - "];
                                
                                for (NSString * h in horarTemps)
                                {
                                    
                                    if([h isEqualToString:@"Todo el día"])
                                    {
                                        NSString * stringFecha = [formatter stringFromDate:fechaTemp];
                                        
                                        Horario * horario = [[Horario alloc] init];
                                        horario.horaInicio = [formatoHora dateFromString:[NSString stringWithFormat:@"%@ %@", stringFecha, @"00:00am"]];
                                        horario.horaFin = [formatoHora dateFromString:[NSString stringWithFormat:@"%@ %@", stringFecha, @"11:59pm"]];
                                        
                                        //NSLog(@"Hora inicio: %@", horario.horaInicio );
                                        //NSLog(@"Hora fin: %@", horario.horaFin );
                                        
                                        regla.todoElDia = YES;
                                        [regla.horarios addObject:horario];
                                    }
                                    else if(![h isEqualToString:@""] && ![h isEqualToString:@"N/A"])
                                    {
                                        
                                        Horario * horario = [[Horario alloc] init];
                                        
                                        NSString * horaIni = [[h componentsSeparatedByString:@" a "] objectAtIndex:0];
                                        NSString * horaFin = [[h componentsSeparatedByString:@" a "] objectAtIndex:1];
                                        NSString * stringFecha = [formatter stringFromDate:fechaTemp];
                                        
                                        horario.horaInicio = [formatoHora dateFromString:[NSString stringWithFormat:@"%@ %@", stringFecha, horaIni]];
                                        horario.horaFin = [formatoHora dateFromString:[NSString stringWithFormat:@"%@ %@", stringFecha, horaFin]];
                                        
                                        //NSLog(@"Hora inicio: %@", horario.horaInicio );
                                        
                                        [regla.horarios addObject:horario];
                                    }
                                }
                                
                                [tipoN.reglas addObject:regla];
                                [reglasTemp addObject:regla];
                            }
                            
                        }
                        
                    }
                }
                
                if(!encontroCiudad || !encontroTipo)
                {
                    NSLog(@"Error en la lectura");
                    return  NO;
                }
                
            }
            
        }
        
    }
    
    
    // Lectura de tabla de tipos de vehiculos
    
    Columna * colCiudad = [tiposVehiculos.columnas objectAtIndex:0];
    Columna * colTipo = [tiposVehiculos.columnas objectAtIndex:1];
    // Columna * colFormato = [tiposVehiculos.columnas objectAtIndex:2];
    //Columna * colVigIni = [tiposVehiculos.columnas objectAtIndex:2];
    Columna * colVigFin = [tiposVehiculos.columnas objectAtIndex:2];
    
    for( int i = 0; i < colCiudad.datos.count; i++)
    {
        BOOL encontroCiudad = NO;
        BOOL encontroTipo = NO;
        for( int j = 0; j < ciudades.count && !encontroCiudad; j++)
        {
            Ciudad * ciudad = [ciudades objectAtIndex:j];
            if([ciudad.nombre isEqualToString:[colCiudad.datos objectAtIndex:i]])
            {
                encontroCiudad = YES;
                
                for( int k = 0; k < ciudad.tiposVehiculos.count && !encontroTipo; k++)
                {
                    TipoVehiculo * tipo = [ciudad.tiposVehiculos objectAtIndex:k];
                    if([tipo.tipo isEqualToString:[colTipo.datos objectAtIndex:i]])
                    {
                        encontroTipo = YES;
                        
                        // tipo.formato = [[colFormato.datos objectAtIndex:i] integerValue];
                        //tipo.inicioVigencia = [formatter dateFromString:[colVigIni.datos objectAtIndex:i]];
                        tipo.finalVigencia = [formatter dateFromString:[colVigFin.datos objectAtIndex:i]];
                        
                        
                        // Manejar indefinido
                        
                        /*
                         if( !tipo.inicioVigencia )
                         {
                         tipo.inicioVigencia = [formatter dateFromString:@"29/08/2001"];
                         }
                         if( !tipo.finalVigencia )
                         {
                         tipo.finalVigencia = [formatter dateFromString:@"29/08/2101"];
                         }*/
                        
                    }
                }
                
            }
        }
    }
    
    
    picoYPlaca.ciudades = ciudades;
    return YES;
    
}


- (void) cargarTipoVehiculosFavoritos
{
    picoYPlaca.favorito = nil;
    picoYPlaca.favoritos = [[NSMutableArray alloc] init];
    
    NSMutableDictionary * dict = [persistencia cargarTipoVehiculosFavoritos];
    
    if( dict == nil)
    {
        return;
    }
    NSString * favorito = [dict objectForKey:@"favorito"];
    NSMutableArray * favs = [dict objectForKey:@"lista favoritos"];
    
    if (![favorito isEqualToString:@"Null"])
    {
        NSString * ciudad = [[favorito componentsSeparatedByString:@" - "] objectAtIndex:0];
        NSString * tipo = [[favorito componentsSeparatedByString:@" - "] objectAtIndex:1];
        
        BOOL encontroCiudad = NO;
        
        for (int i = 0; i < picoYPlaca.ciudades.count && !encontroCiudad; i++)
        {
            BOOL encontroTipo = NO;
            Ciudad * ciu = [picoYPlaca.ciudades objectAtIndex:i];
            
            if([ciu.nombre isEqualToString:ciudad])
            {
                encontroCiudad = YES;
                for (int j = 0; j < ciu.tiposVehiculos.count && !encontroTipo; j++)
                {
                    TipoVehiculo * tip = [ciu.tiposVehiculos objectAtIndex:j];
                    
                    if([tip.tipo isEqualToString:tipo])
                    {
                        encontroTipo = YES;
                        picoYPlaca.favorito = tip;
                    }
                }
            }
        }
        
    }
    
    for (NSString * fav in favs)
    {
        
        if(![[fav stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""])
        {
            NSString * ciudad = [[fav componentsSeparatedByString:@" - "] objectAtIndex:0];
            NSString * tipo = [[fav componentsSeparatedByString:@" - "] objectAtIndex:1];
            
            
            BOOL encontroCiudad = NO;
            
            
            for (int i = 0; i < picoYPlaca.ciudades.count && !encontroCiudad; i++)
            {
                BOOL encontroTipo = NO;
                Ciudad * ciu = [picoYPlaca.ciudades objectAtIndex:i];
                
                if([ciu.nombre isEqualToString:ciudad])
                {
                    encontroCiudad = YES;
                    for (int j = 0; j < ciu.tiposVehiculos.count && !encontroTipo; j++)
                    {
                        TipoVehiculo * tip = [ciu.tiposVehiculos objectAtIndex:j];
                        
                        if([tip.tipo isEqualToString:tipo])
                        {
                            encontroTipo = YES;
                            [picoYPlaca.favoritos addObject:tip];
                        }
                    }
                }
            }
        }
    }
    
    
}

- (void) guardarTipoVehiculosFavoritos
{
    
    NSString * favorito = @"Null";
    
    if(picoYPlaca.favorito != nil)
    {
        favorito = [NSString stringWithFormat:@"%@ - %@", picoYPlaca.favorito.ciudad.nombre,  picoYPlaca.favorito.tipo];[NSString stringWithFormat:@"%@ - %@", picoYPlaca.favorito.ciudad.nombre,  picoYPlaca.favorito.tipo];
    }
    
    NSMutableArray * favs = [[NSMutableArray alloc] init];
    
    for (TipoVehiculo * tip in  picoYPlaca.favoritos)
    {
        NSString * temp = [NSString stringWithFormat:@"%@ - %@", tip.ciudad.nombre,  tip.tipo];
        [favs addObject:temp];
    }
    
    
    
    [persistencia guardarTipoVehiculoFav:favorito conListaFavoritos:favs];
    
}

@end
